package com.changgou.seckill.schedul;

import com.changgou.seckill.dao.SeckillGoodsMapper;
import com.changgou.seckill.pojo.SeckillGoods;
import entity.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;
import java.util.Set;

@Component
public class SeckillGoodsPushTask {

    @Autowired
    private SeckillGoodsMapper seckillGoodsMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    /****
     * 每30秒执行一次
     */
    @Scheduled(cron = "0/30 * * * * ?")
    public void loadGoodsPushRedis() {
        //获取时间段列表
        List<Date> dateMenus = DateUtil.getDateMenus();
        //根据时间段获取商品数据
        for (Date startTime : dateMenus) {
            Date endTime = DateUtil.addDateHour(startTime, 2);
            //redis缓存命名空间 namespace = SeckillGoods_20195712
            String extName = DateUtil.data2str(startTime, DateUtil.PATTERN_YYYYMMDDHH);
            //构造查询条件
            Example example = new Example(SeckillGoods.class);
            Example.Criteria criteria = example.createCriteria();
            //审核通过
            criteria.andEqualTo("status", "1");
            //剩余库存大于0
            criteria.andGreaterThan("stockCount", 0);
            //商品开始时间>=活动开始时间
            criteria.andGreaterThanOrEqualTo("startTime", startTime);
            //商品结束时间<活动结束时间
            criteria.andLessThan("endTime", endTime);
            //排除之前已经加入到redis缓存中的数据
            Set keys = redisTemplate.boundHashOps("SeckillGoods_" + extName).keys();
            if (keys != null && keys.size() > 0) {
                criteria.andNotIn("id", keys);
            }

            //从数据库查询数据
            List<SeckillGoods> seckillGoodses = seckillGoodsMapper.selectByExample(example);

            for (SeckillGoods seckillGoods : seckillGoodses) {
                //将数据存储到redis
                redisTemplate.boundHashOps("SeckillGoods_" + extName).put(seckillGoods.getId().toString(), seckillGoods);
                //添加一个商品库存队列
                Long[] queue = getQueue(seckillGoods);
                redisTemplate.boundListOps("SeckillGoodsCountList_" + seckillGoods.getId()).leftPushAll(queue);
                //添加一个计数器
                redisTemplate.boundHashOps("SeckillGoodsCount").increment(seckillGoods.getId().toString(), seckillGoods.getStockCount());
            }
        }
    }


    /****
     * 封装商品库存队列
     * @param seckillGoods
     * @return
     */
    private Long[] getQueue(SeckillGoods seckillGoods) {
        Integer stockCount = seckillGoods.getStockCount();
        Long[] ids = new Long[stockCount];
        for (int i = 0; i < stockCount; i++) {
            ids[i] = seckillGoods.getId();
        }
        return ids;
    }
}

